#include "cmd_bind.h"
#include "mem_manager.h"
#include "io_console.h"
#include "cmd_parser.h"

#include <string.h>

typedef struct 
{
	char	*keyName;
	int		keyCode;
}TKeyName;

static TKeyName keyNames[] =
{	{"NONE",		K_NONE},
	{"BACKSPACE", 	K_BACKSPACE},
	{"TAB",	    	K_TAB},
	{"ENTER",		K_ENTER},
	{"ESCAPE",		K_ESCAPE},
	{"SPACE",		K_SPACE},
	
	{"SHIFT",		K_SHIFT},
	{"CTRL",		K_CTRL},
	{"ALT",			K_ALT},
	{"PAUSE",		K_PAUSE},
	{"CAPS",		K_CAPS},
	{"TILDE",		K_TILDE},
	
	{"INS",			K_INS},
	{"DEL",			K_DEL},
	{"HOME",		K_HOME},
	{"END",			K_END},
	{"PGUP",		K_PGUP},
	{"PGDN",		K_PGDN},
	
	{"UPARROW",		K_UPARROW},
	{"DOWNARROW",	K_DOWNARROW},
	{"LEFTARROW",	K_LEFTARROW},
	{"RIGHTARROW",	K_RIGHTARROW},
	
	{"KP_0",		K_KP_0},
	{"KP_1",		K_KP_1},
	{"KP_2",		K_KP_2},
	{"KP_3",		K_KP_3},
	{"KP_4",		K_KP_4},
	{"KP_5",		K_KP_5},
	{"KP_6",		K_KP_6},
	{"KP_7",		K_KP_7},
	{"KP_8",		K_KP_8},
	{"KP_9",		K_KP_9},
	{"KP_DIVIDE",	K_KP_DIVIDE},
	{"KP_MULTIPLY",	K_KP_MULTIPLY},
	{"KP_MINUS",	K_KP_MINUS},
	{"KP_PLUS",		K_KP_PLUS},
	{"KP_ENTER",	K_KP_ENTER},
	{"KP_PERIOD",	K_KP_PERIOD},
	
	{"MINUS",		K_MINUS},
	{"PLUS",		K_PLUS},
	{"LBRACKET",	K_LBRACKET},
	{"RBRACKET",	K_RBRACKET},
	{"BACKSLASH",	K_BACKSLASH},
	{"SEMICOLON",	K_SEMICOLON},
	{"QUOTE",		K_QUOTE},
	{"COMMA",		K_COMMA},
	{"PERIOD",		K_PERIOD},
	{"SLASH",		K_SLASH},
	
	{"F1",			K_F1},
	{"F2",			K_F2},
	{"F3",			K_F3},
	{"F4",			K_F4},
	{"F5",			K_F5},
	{"F6",			K_F6},
	{"F7",			K_F7},
	{"F8",			K_F8},
	{"F9",			K_F9},
	{"F10",			K_F10},
	{"F11",			K_F11},
	{"F12",			K_F12},
	{"F13",			K_F13},
	{"F14",			K_F14},
	{"F15",			K_F15},
	
	{"MOUSE1",		K_MOUSE1},
	{"MOUSE2",		K_MOUSE2},
	{"MOUSE3",		K_MOUSE3},
	{"MOUSE4",		K_MOUSE4},
	{"MOUSE5",		K_MOUSE5},
	{"MOUSE6",		K_MOUSE6},
	{"MOUSE7",		K_MOUSE7},
	{"MOUSE8",		K_MOUSE8},
	
	{"MWHEELDOWN",	K_MWHEELDOWN},
	{"MWHEELUP",	K_MWHEELUP},
	
	{"JOY1",		K_JOY1},
	{"JOY2",		K_JOY2},
	{"JOY3",		K_JOY3},
	{"JOY4",		K_JOY4},
	{"JOY5",		K_JOY5},
	{"JOY6",		K_JOY6},
	{"JOY7",		K_JOY7},
	{"JOY8",		K_JOY8},
	{"JOY9",		K_JOY9},
	{"JOY10",		K_JOY10},
	{"JOY11",		K_JOY11},
	{"JOY12",		K_JOY12},
	{"JOY13",		K_JOY13},
	{"JOY14",		K_JOY14},
	{"JOY15",		K_JOY15},
	{"JOY16",		K_JOY16},
	{"JOY17",		K_JOY17},
	{"JOY18",		K_JOY18},
	{"JOY19",		K_JOY19},
	{"JOY20",		K_JOY20},
	{"JOY21",		K_JOY21},
	{"JOY22",		K_JOY22},
	{"JOY23",		K_JOY23},
	{"JOY24",		K_JOY24},
	{"JOY25",		K_JOY25},
	{"JOY26",		K_JOY26},
	{"JOY27",		K_JOY27},
	{"JOY28",		K_JOY28},
	{"JOY29",		K_JOY29},
	{"JOY30",		K_JOY30},
	{"JOY31",		K_JOY31},
	{"JOY32",		K_JOY32},
	
	{"AUX1",		K_AUX1},
	{"AUX2",		K_AUX2},
	{"AUX3",		K_AUX3},
	{"AUX4",		K_AUX4},
	{"AUX5",		K_AUX5},
	{"AUX6",		K_AUX6},
	{"AUX7",		K_AUX7},
	{"AUX8",		K_AUX8},
	{"AUX9",		K_AUX9},
	{"AUX10",		K_AUX10},
	{"AUX11",		K_AUX11},
	{"AUX12",		K_AUX12},
	{"AUX13",		K_AUX13},
	{"AUX14",		K_AUX14},
	{"AUX15",		K_AUX15},
	{"AUX16",		K_AUX16},

	{NULL,0}
};

static char* binds[K_LAST_KEY];
static bool keyDown[K_LAST_KEY];
static char shortKeyName[2];

void cmd_initBind()
{
	for (int i=0;i<K_LAST_KEY;i++)
		binds[i] = NULL;

	shortKeyName[1] = 0;
}

void cmd_shutdownBind()
{
	for (int i=0;i<K_LAST_KEY;i++)
		g_free(binds[i]);
}

void cmd_bind(int key, const char* cmd)
{
	g_free(binds[key]);
	if (cmd)
		g_strdup(binds[key], cmd);
}

const char* cmd_getBind(int key)
{
	return binds[key];
}

const char* cmd_getKeyName(int key)
{
	if (((key>='A')&&(key<='Z'))||((key>='0')&&(key<='9')))
	{
		shortKeyName[0] = key;
		return shortKeyName;
	}

	for (int i=0;keyNames[i].keyName;i++)
		if (keyNames[i].keyCode == key)
			return keyNames[i].keyName;

	return NULL;
}

int cmd_getKeyCode(const char* name)
{
	if (name[1]==0)
	{
		if (((name[0]>='A')&&(name[0]<='Z'))||((name[0]>='0')&&(name[0]<='9')))
			return name[0];
		return 0;
	}

	for (int i=0;keyNames[i].keyName;i++)
		if (!strcmp(keyNames[i].keyName, name))
			return keyNames[i].keyCode;

	return 0;
}

void cmd_keyDown(int key)
{
	if (!keyDown[key])
	{
		keyDown[key] = true;
		const char *cmd = cmd_getBind(key);
		if (cmd)
		{
			if (cmd[0] != '-')		
				cmd_exec(cmd);
		}
	}
}

void cmd_keyUp(int key)
{
	if (keyDown[key])
	{
		keyDown[key] = false;
		char *cmd = (char*)cmd_getBind(key);
		if (cmd)
		{
			if (cmd[0] == '+')
			{
				cmd[0] = '-';
				cmd_exec(cmd);
				cmd[0] = '+';
			}
			else
			{
				if (cmd[0] == '-')
					cmd_exec(cmd);
			}
		}
	}
}
